package fourthweek.Array;

import fourthweek.ElementNotFoundException;
import fourthweek.ListADT;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class ArrayList<T> implements Iterable<T>, ListADT<T> {

    private final static int DEFAULT_CAPACITY = 100;
    private final static int NOT_FOUND = -1;
    protected int rear;
    protected T[] list;
    protected int modCount;
    public ArrayList() {
        this(DEFAULT_CAPACITY);
    }
    public ArrayList(int initialCapacity) {
        rear = 0;
        list = (T[]) (new Object[initialCapacity]);
        modCount = 0;
    }
    private int find(T elem) {
        int scan = 0;
        int result = NOT_FOUND;

        if (!isEmpty())
            while (result == NOT_FOUND && scan < rear) {
                if (elem.equals(list[scan]))
                    result = scan;
                else
                    scan++;
            }
        return result;
    }
    @Override
    public boolean contains(T target) {
        return (find(target) != NOT_FOUND);
    }
    @Override
    public T removeFirst() {
        T result;
        if (isEmpty())
            throw new ElementNotFoundException("ArrayList");
        else {
            result = list[0];
            rear--;
            for(int a = 0; a < rear; a++){
                list[a] = list[a + 1];
            }
            list[rear] = null;
        }
        return result;
    }
    @Override
    public T removeLast() {
        T result = list[rear - 1];
        list[rear] = null;
        rear--;
        return result;
    }
    @Override
    public T remove(T element) {
        T result;
        int index = find(element);
        if (index == NOT_FOUND) {
            throw new ElementNotFoundException("ArrayList");
        }
        result = list[index];
        rear--;

        for (int i = index; i < rear; i++) {
            list[i] = list[i + 1];
        }
        list[rear] = null;
        modCount++;
        return result;
    }
    @Override
    public T first() {
        if (isEmpty())
            throw new ElementNotFoundException("ArrayList");
        else
            return list[0];
    }
    @Override
    public T last() {
        if (isEmpty())
            throw new ElementNotFoundException("ArrayList");
        else
            return list[rear - 1];
    }
    @Override
    public boolean isEmpty() {
        return rear == 0;
    }
    @Override
    public int size() {
        return rear;
    }
    @Override
    public String toString() {
        String result = "";
        for(int temp = 0; temp < rear; temp++){
            result += list[temp] + " ";
        }
        return result;
    }

    @Override
    public Iterator<T> iterator() {
        return new ArrayListIterator();
    }
    protected void expandCapacity() {
        list = Arrays.copyOf(list, list.length * 2);
    }
    private class ArrayListIterator implements Iterator<T> {
        int iteratorModCount;
        int current;
        public ArrayListIterator() {
            iteratorModCount = modCount;
            current = 0;
        }
        public boolean hasNext() throws ConcurrentModificationException {
            if (iteratorModCount != modCount)
                throw new ConcurrentModificationException();
            return (current < rear);
        }
        public T next() throws ConcurrentModificationException {
            if (!hasNext())
                throw new NoSuchElementException();

            current++;

            return list[current - 1];
        }
        public void remove() throws UnsupportedOperationException {
            throw new UnsupportedOperationException();
        }
    }
}

